Learn in 10 minutes

Learn in 10 minutes

Python in 10 Minuten lernen

Python ist eine hochentwickelte, interpretierte Programmiersprache, die für ihre prägnante Syntax und leistungsstarken Funktionen bekannt ist. Dieses Tutorial basiert auf der neuesten Python 3.13+ Version und hilft Ihnen, Python schnell zu lernen.

1. Ihr erstes Python-Programm schreiben

Beginnen wir mit einem einfachen Programm. Erstellen Sie eine Datei namens hello.py und geben Sie den folgenden Code ein:

print("Hallo, Welt!")

Speichern Sie die Datei und führen Sie den folgenden Befehl im Terminal oder in der Kommandozeile aus:

python hello.py

Die Ausgabe wird sein:

Hallo, Welt!

Dieses einfache Programm demonstriert die grundlegende Ausgabefunktion von Python. Die print()-Funktion wird verwendet, um Textinformationen in der Konsole anzuzeigen.

2. Grundlegende Syntax

Die Syntax von Python ist einfach und leicht verständlich. Python verwendet Einrückungen, um Codeblöcke zu definieren, im Gegensatz zu anderen Sprachen, die geschweifte Klammern {} verwenden.

# Dies ist ein Kommentar
print("Hallo, Welt!")

Grundlegende Syntaxregeln in Python:

  • Einrückung: Standardmäßig werden 4 Leerzeichen verwendet, um die Ebene eines Codeblocks anzugeben. Zum Beispiel muss Code innerhalb von Funktionen oder Schleifen eingerückt sein.
  • Kommentare: Einzeilige Kommentare beginnen mit #, während mehrzeilige Kommentare dreifache Anführungszeichen """ oder ''' verwenden.
  • Anweisungen: In der Regel eine Anweisung pro Zeile, kein Semikolon ; am Zeilenende erforderlich.
  • Codeblöcke: Werden durch Einrückung definiert, wie bei if, for oder Funktionskörpern.

Beispiel mit mehrzeiligen Kommentaren:

"""
Dies ist ein mehrzeiliger Kommentar,
der sich über mehrere Zeilen erstreckt.
"""

Einrückung ist ein zentrales Merkmal der Python-Syntax und wird verwendet, um die hierarchische Struktur von Codeblöcken zu definieren:

if True:
    print("Diese Zeile ist eingerückt")
    print("Diese Zeile ist auch eingerückt")
print("Diese Zeile ist nicht eingerückt")

3. Variablen und Datentypen

In Python sind Variablen Container zur Speicherung von Daten. Python ist eine dynamisch typisierte Sprache, was bedeutet, dass Sie den Typ einer Variable nicht im Voraus deklarieren müssen.

Grundlegende Regeln für Variablennamen:

  • Variablennamen dürfen nur Buchstaben, Zahlen und Unterstriche enthalten.
  • Variablennamen dürfen nicht mit einer Zahl beginnen.
  • Variablennamen sind case-sensitive.
  • Python-Schlüsselwörter können nicht als Variablennamen verwendet werden.

Der Typ einer Variable wird durch den zugewiesenen Wert bestimmt. Die wichtigsten grundlegenden Datentypen in Python sind:

  • Ganzzahl (int): z. B. 42 oder -10, ohne Größenbegrenzung.
  • Gleitkommazahl (float): z. B. 3.14 oder 2.5e3 (wissenschaftliche Notation).
  • Zeichenkette (str): z. B. "hallo" oder 'welt', mit einfachen oder doppelten Anführungszeichen.
  • Boolescher Wert (bool): True oder False.
  • NoneType (None): Wird durch None dargestellt und zeigt einen Null- oder keinen Wert an.

Python unterstützt Typ-Hinweise, um die Lesbarkeit des Codes zu verbessern, die für statische Überprüfungen und IDE-Unterstützung verwendet werden, ohne das Laufzeitverhalten zu beeinflussen:

name: str = "Alice"
age: int = 25

3.1 Numerische Typen (Number)

Python unterstützt drei numerische Typen: Ganzzahl (int), Gleitkommazahl (float) und komplex (complex).

# Ganzzahl
age = 25
population = 1000000

# Gleitkommazahl
temperature = 36.5
pi = 3.14159

# Komplex
complex_num = 3 + 4j

3.2 Zeichenkette (String)

Zeichenketten sind Sequenzen von Zeichen, die in einfache oder doppelte Anführungszeichen eingeschlossen sind.

single_quote = 'Zeichenkette mit einfachen Anführungszeichen'
double_quote = "Zeichenkette mit doppelten Anführungszeichen"
multiline = """Dies ist eine
mehrzeilige Zeichenkette"""

Zeichenkettenoperationen:

text = "Python-Programmierung"
print(len(text))        # Länge der Zeichenkette
print(text.upper())     # In Großbuchstaben umwandeln
print(text.lower())     # In Kleinbuchstaben umwandeln
print(text[0])          # Zugriff auf das erste Zeichen
print(text[2:6])        # Zeichenkettenslicing

3.3 Boolescher Typ (Boolean)

Der boolesche Typ hat zwei Werte: True und False.

is_active = True
is_complete = False

# Boolesche Operationen
result1 = True and False  # False
result2 = True or False   # True
result3 = not True        # False

3.4 None-Typ (None)

None repräsentiert einen Null- oder keinen Wert-Zustand.

value = None

if value is None:
    print("Wert ist null")

4. Datenstrukturen

Python bietet mehrere integrierte Datenstrukturen zur Speicherung und Bearbeitung von Daten. Nachfolgend sind die häufig verwendeten Datenstrukturen und deren Nutzung aufgeführt.

4.1 Liste (List)

Eine Liste ist eine geordnete und veränderbare Sammlung. Sie können Elemente hinzufügen, entfernen oder ändern. Listen werden mit eckigen Klammern [] definiert.

numbers = [1, 2, 3, 4, 5]
numbers.append(6)      # Element hinzufügen
numbers.insert(0, 0)   # An bestimmter Position einfügen
numbers.remove(3)      # Bestimmten Wert entfernen
numbers[0] = 10        # Element ändern
print(numbers)         # [10, 2, 4, 5, 6]

Listenslicing zur Auswahl von Teillisten:

numbers = [10, 20, 30, 40, 50]
print(numbers[1:4])    # Ausgabe: [20, 30, 40]
print(numbers[:3])     # Ausgabe: [10, 20, 30]
print(numbers[-2:])    # Ausgabe: [40, 50]

Listenabstraktion:

squares = [x**2 for x in range(5)]
print(squares)         # [0, 1, 4, 9, 16]

even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)    # [0, 4, 16, 36, 64]

4.2 Tupel (Tuple)

Ein Tupel ist eine geordnete, aber unveränderbare Sammlung. Nach der Erstellung können die Elemente nicht mehr geändert werden. Tupel werden mit runden Klammern () definiert. Aufgrund ihrer Unveränderbarkeit sind Tupel im Allgemeinen schneller als Listen und können als Schlüssel für Wörterbücher verwendet werden.

point = (10, 20)
x, y = point  # Entpacken
print(x, y)   # Ausgabe: 10 20

Einzelelement-Tupel benötigen ein Komma:

single_tuple = (42,)

4.3 Wörterbuch (Dict)

Ein Wörterbuch ist eine ungeordnete (ab Python 3.7+ geordnete) Sammlung von Schlüssel-Wert-Paaren. Jeder Schlüssel ist eindeutig und mit einem Wert verknüpft. Wörterbücher werden mit geschweiften Klammern {} definiert.

student = {
    "name": "John",
    "age": 20,
    "major": "Informatik"
}

# Zugriff und Änderung des Wörterbuchs
print(student["name"])
student["age"] = 21
student["gpa"] = 3.8

# Sicherer Zugriff
print(student.get("phone", "Nicht angegeben"))

# Iteration über das Wörterbuch
for key, value in student.items():
    print(f"{key}: {value}")

Wörterbuchabstraktion:

# Erstellung eines Quadrate-Wörterbuchs
squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# Bedingte Wörterbuchabstraktion
even_squares_dict = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares_dict)  # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

4.4 Menge (Set)

Eine Menge ist eine ungeordnete Sammlung ohne doppelte Elemente. Sie wird mit geschweiften Klammern {} oder set() definiert.

# Erstellung einer Menge
fruits = {"apple", "banana", "orange"}
numbers = set([1, 2, 3, 3, 4, 4, 5])  # Automatische Entfernung von Duplikaten
print(numbers)  # {1, 2, 3, 4, 5}

# Mengenoperationen
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(set1 | set2)  # Vereinigung: {1, 2, 3, 4, 5, 6}
print(set1 & set2)  # Schnittmenge: {3, 4}
print(set1 - set2)  # Differenz: {1, 2}
print(set1 ^ set2)  # Symmetrische Differenz: {1, 2, 5, 6}

5. Operationen und Operatoren

Python bietet eine Vielzahl von Operatoren für verschiedene Berechnungen und Vergleiche, einschließlich arithmetischer, Vergleichs-, logischer, bitweiser und Identitätsoperatoren.

  • Arithmetische Operatoren: +, -, *, /, // (Ganzzahldivision), % (Modulus), ** (Potenz).
  • Vergleichsoperatoren: ==, !=, >, <, >=, <=.
  • Logische Operatoren: and, or, not.
  • Zugehörigkeitsoperatoren: in, not in.
  • Identitätsoperatoren: is, is not.

5.1 Arithmetische Operatoren

Arithmetische Operatoren werden für mathematische Operationen verwendet. Die Operatorpriorität folgt mathematischen Regeln (z. B. hat ** eine höhere Priorität als + oder -). Klammern () können verwendet werden, um die Priorität zu ändern.

a, b = 10, 3

print(f"Addition: {a + b}")      # 13
print(f"Subtraktion: {a - b}")   # 7
print(f"Multiplikation: {a * b}")  # 30
print(f"Division: {a / b}")      # 3.333...
print(f"Ganzzahldivision: {a // b}")  # 3
print(f"Modulus: {a % b}")      # 1
print(f"Potenzierung: {a ** b}")  # 1000

5.2 Vergleichsoperatoren

Vergleichsoperatoren vergleichen zwei Werte und geben einen booleschen Wert (True oder False) zurück.

x, y = 5, 10

print(f"Gleich: {x == y}")     # False
print(f"Ungleich: {x != y}")   # True
print(f"Größer als: {x > y}")  # False
print(f"Kleiner als: {x < y}")  # True
print(f"Größer oder gleich: {x >= y}")  # False
print(f"Kleiner oder gleich: {x <= y}")  # True

5.3 Logische Operatoren

Logische Operatoren kombinieren oder manipulieren boolesche Werte (True oder False) und werden typischerweise in Bedingungsanweisungen verwendet.

a, b = True, False

print(f"UND-Operation: {a and b}")  # False
print(f"ODER-Operation: {a or b}")    # True
print(f"NICHT-Operation: {not a}")    # False

5.4 Identitätsoperatoren

Der is-Operator vergleicht die Identität zweier Objekte und prüft, ob sie auf dieselbe Speicheradresse verweisen (nicht nur gleiche Werte). Er unterscheidet sich von ==, der Inhalte vergleicht.

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1

print(f"list1 ist list2: {list1 is list2}")    # False
print(f"list1 ist list3: {list1 is list3}")    # True
print(f"list1 == list2: {list1 == list2}")    # True

5.5 Zugehörigkeitsoperatoren

Zugehörigkeitsoperatoren prüfen, ob ein Wert Mitglied einer Sequenz (z. B. Liste, Tupel, Zeichenkette, Menge) ist und geben einen booleschen Wert zurück.

fruits = ["apple", "banana", "orange"]

print(f"'apple' in fruits: {'apple' in fruits}")        # True
print(f"'grape' not in fruits: {'grape' not in fruits}")  # True

6. Kontrollfluss

Python bietet mehrere Kontrollflussanweisungen, um die Ausführungsreihenfolge eines Programms zu steuern.

6.1 if-Anweisungen

Die if-Anweisung bewertet eine Bedingung und führt ihren Block aus, wenn die Bedingung True ist. Verwenden Sie elif und else für komplexe Bedingungen.

age = 20
if age >= 18:
    print("Erwachsener")
elif age >= 13:
    print("Teenager")
else:
    print("Kind")

6.2 for-Schleifen

Die for-Schleife iteriert über ein iterierbares Objekt (z. B. Liste, Tupel, Zeichenkette oder Bereich).

# Iteration über eine Liste
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# Verwendung von range() für Schleifen
for i in range(5):
    print(i)  # Ausgabe: 0, 1, 2, 3, 4

6.3 while-Schleifen

Die while-Schleife führt einen Block aus, solange ihre Bedingung True bleibt.

count = 0
while count < 5:
    print(count)
    count += 1
  • break und continue: break beendet die Schleife, continue überspringt die aktuelle Iteration.
for i in range(10):
    if i == 5:
        break
    if i % 2 == 0:
        continue
    print(i)  # Ausgabe: 1, 3

6.4 match-Anweisungen

Eingeführt in Python 3.10, bietet die match-Anweisung leistungsstarkes strukturelles Mustervergleich, das als fortgeschrittene Alternative zu if/elif/else-Ketten dient.

http_status = 200

match http_status:
    case 200 | 201:
        print("Erfolg")
    case 404:
        print("Nicht gefunden")
    case 500:
        print("Serverfehler")
    case _:  # Platzhalter, passt auf jeden anderen Fall
        print("Unbekannter Status")

7. Ein- und Ausgabe

7.1 Grundlegende Ein- und Ausgabe

Verwenden Sie die input()-Funktion, um Benutzereingaben zu erhalten, und die print()-Funktion, um Informationen auszugeben.

# Benutzereingabe erhalten
name = input("Bitte geben Sie Ihren Namen ein: ")
age = int(input("Bitte geben Sie Ihr Alter ein: "))

# Informationen ausgeben
print("Willkommen", name)
print("Sie sind", age, "Jahre alt")

7.2 Formatierte Ausgabe (f-Strings)

Eingeführt in Python 3.6+, sind f-Strings (formatierte Zeichenkettenliterale) eine bequeme und leistungsstarke Möglichkeit, Zeichenketten zu formatieren. Präfixieren Sie eine Zeichenkette mit f oder F und betten Sie Variablen oder Ausdrücke in geschweifte Klammern {} ein.

user = "Alice"
items = 3
total_cost = 45.5

# Verwendung von f-String für formatierte Nachricht
message = f"Benutzer {user} hat {items} Artikel für ${total_cost:.2f} gekauft."
print(message)

# Ausdrücke in f-Strings
print(f"2 + 3 ergibt {2 + 3}")

Ausdrücke und Funktionsaufrufe in f-Strings:

width = 10
height = 5

# Verwendung von Ausdrücken in f-Strings
area = f"Rechteckfläche: {width * height}"
print(area)

# Funktionen aufrufen
text = "python"
formatted = f"Großbuchstaben: {text.upper()}, Länge: {len(text)}"
print(formatted)

Formatierungsoptionen in f-Strings:

pi = 3.14159265359
large_number = 1234567

# Zahlenformatierung
print(f"Pi (2 Dezimalstellen): {pi:.2f}")
print(f"Pi (4 Dezimalstellen): {pi:.4f}")
print(f"Große Zahl (Tausender): {large_number:,}")
print(f"Prozentsatz: {0.85:.1%}")

# Zeichenkettenausrichtung
name = "Python"
print(f"Links ausrichten: '{name:<10}'")
print(f"Rechts ausrichten: '{name:>10}'")
print(f"Zentriert ausrichten: '{name:^10}'")

Datums- und Zeitformatierung mit f-Strings:

from datetime import datetime

now = datetime.now()
print(f"Aktuelle Zeit: {now}")
print(f"Formatierte Zeit: {now:%Y-%m-%d %H:%M:%S}")
print(f"Nur Datum: {now:%Y-%m-%d}")

9. Funktionen

Funktionen in Python sind wiederverwendbare Codeblöcke für spezifische Aufgaben, die mit dem def-Schlüsselwort definiert werden und Standardparameter, variable Argumente und Schlüsselwortargumente unterstützen.

Grundlegende Funktionsdefinition:

def greet(name):
    """Begrüßungsfunktion"""
    return f"Hallo, {name}!"

# Aufruf der Funktion
message = greet("John")
print(message)

Schlüsselwortargumente:

Schlüsselwortargumente werden mit der Syntax parameter_name=value übergeben.

def greet(name, greeting="Hallo"):
    return f"{greeting}, {name}!"

print(greet("Alice"))          # Ausgabe: Hallo, Alice!
print(greet("Bob", "Hi"))     # Ausgabe: Hi, Bob!

Variable Argumente:

Variable Argumente ermöglichen es Funktionen, eine beliebige Anzahl von Argumenten zu akzeptieren, entweder positional (*args) oder als Schlüsselwort (**kwargs).

# Positionale variable Argumente (*args)
def sum_numbers(*args):
    return sum(args)

print(sum_numbers(1, 2, 3, 4))  # Ausgabe: 10

# Schlüsselwortvariable Argumente (**kwargs)
def print_kwargs(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_kwargs(name="Alice", age=25, city="Berlin")

Funktionsannotationen:

Funktionsannotationen fügen den Funktionsparametern und Rückgabewerten beschreibende Metadaten hinzu, um die Lesbarkeit und Dokumentation zu verbessern.

def calculate_area(length: float, width: float) -> float:
    """Berechnet die Rechteckfläche"""
    return length * width

def process_user(name: str, age: int, active: bool = True) -> dict:
    """Verarbeitet Benutzerinformationen"""
    return {
        "name": name,
        "age": age,
        "active": active
    }

10. Lambda-Ausdrücke

Lambda-Ausdrücke erstellen anonyme Funktionen und bieten eine prägnante Möglichkeit, kleine Funktionen zu definieren.

square = lambda x: x ** 2
print(square(5))  # Ausgabe: 25

Häufig verwendet mit höherwertigen Funktionen wie map oder filter:

numbers = [1, 2, 3, 4]
squares = list(map(lambda x: x ** 2, numbers))
print(squares)  # Ausgabe: [1, 4, 9, 16]

11. Klassen und Objekte

Python unterstützt objektorientierte Programmierung mit dem class-Schlüsselwort:

class Person:
    """Personenklasse"""
    
    def __init__(self, name, age):
        """Konstruktor"""
        self.name = name
        self.age = age
    
    def introduce(self):
        """Vorstellungsmethode"""
        return f"Ich bin {self.name}, {self.age} Jahre alt"
    
    def have_birthday(self):
        """Geburtstagsmethode"""
        self.age += 1
        return f"{self.name} hatte Geburtstag, jetzt {self.age} Jahre alt"

# Objekte erstellen
person1 = Person("John", 25)
person2 = Person("Jane", 30)

print(person1.introduce())
print(person2.have_birthday())

11.1 Klassen- und Instanzattribute

In Python gibt es zwei Arten von Attributen zur Speicherung von Daten in Klassen und Objekten: Klassenattribute und Instanzattribute.

  • Klassenattribute: Werden außerhalb von Methoden definiert, gehören der Klasse selbst und werden von allen Instanzen geteilt.
  • Instanzattribute: Werden in Methoden (meist __init__) definiert und sind an spezifische Instanzen gebunden über self.
class Student:
    # Klassenattribute
    school = "Universität Stanford"
    student_count = 0
    
    def __init__(self, name, major):
        # Instanzattribute
        self.name = name
        self.major = major
        Student.student_count += 1
    
    @classmethod
    def get_student_count(cls):
        """Klassenmethode"""
        return cls.student_count
    
    @staticmethod
    def is_valid_age(age):
        """Statische Methode"""
        return 0 < age < 150

# Nutzungsbeispiel
student1 = Student("John", "Informatik")
student2 = Student("Jane", "Mathematik")

print(f"Schule: {Student.school}")
print(f"Gesamtzahl der Studenten: {Student.get_student_count()}")
print(f"Gültiges Alter: {Student.is_valid_age(20)}")

11.2 Klassenvererbung

Vererbung ermöglicht es einer Klasse (Unterklasse), Attribute und Methoden von einer anderen Klasse (Oberklasse) zu erben, um Codewiederverwendung und Erweiterung zu ermöglichen.

class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species
    
    def make_sound(self):
        return f"{self.name} macht ein Geräusch"
    
    def info(self):
        return f"{self.name} ist ein {self.species}"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name, "Hund")
        self.breed = breed
    
    def make_sound(self):
        return f"{self.name} bellt"
    
    def fetch(self):
        return f"{self.name} holt den Ball"

class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name, "Katze")
        self.color = color
    
    def make_sound(self):
        return f"{self.name} miaut"
    
    def climb(self):
        return f"{self.name} klettert auf einen Baum"

# Verwendung der Vererbung
dog = Dog("Buddy", "Golden Retriever")
cat = Cat("Mimi", "Orange")

print(dog.info())
print(dog.make_sound())
print(dog.fetch())

print(cat.info())
print(cat.make_sound())
print(cat.climb())

11.3 Spezielle Methoden (Magische Methoden)

Spezielle Methoden (oder magische Methoden) sind doppelt unterstrichene Methoden, die spezifische Verhaltensweisen definieren und automatisch von Python in bestimmten Szenarien aufgerufen werden.

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def __str__(self):
        """Zeichenkettenrepräsentation"""
        return f"Rechteck({self.width}x{self.height})"
    
    def __repr__(self):
        """Offizielle Zeichenkettenrepräsentation"""
        return f"Rectangle(width={self.width}, height={self.height})"
    
    def __eq__(self, other):
        """Gleichheitsvergleich"""
        if isinstance(other, Rectangle):
            return self.width == other.width and self.height == other.height
        return False
    
    def __lt__(self, other):
        """Kleiner-als-Vergleich (nach Fläche)"""
        if isinstance(other, Rectangle):
            return self.area() < other.area()
        return NotImplemented
    
    def __add__(self, other):
        """Additionsoperation"""
        if isinstance(other, Rectangle):
            return Rectangle(self.width + other.width, self.height + other.height)
        return NotImplemented
    
    def area(self):
        """Fläche berechnen"""
        return self.width * self.height

# Verwendung spezieller Methoden
rect1 = Rectangle(3, 4)
rect2 = Rectangle(5, 6)
rect3 = Rectangle(3, 4)

print(rect1)           # Rechteck(3x4)
print(repr(rect1))     # Rectangle(width=3, height=4)
print(rect1 == rect3)  # True
print(rect1 < rect2)   # True
print(rect1 + rect2)   # Rechteck(8x10)

12. Kontextmanager

Kontextmanager gewährleisten eine ordnungsgemäße Ressourcenzuweisung und -freigabe, üblicherweise verwendet mit der with-Anweisung für die Ressourcenverwaltung, wie Dateien oder Datenbankverbindungen.

12.1 Verwendung von Kontextmanagern

Dateioperationen sind ein häufiger Anwendungsfall für Kontextmanager:

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

Die with-Anweisung stellt sicher, dass die Datei nach den Operationen automatisch geschlossen wird.

12.2 Benutzerdefinierte Kontextmanager

Erstellen Sie benutzerdefinierte Kontextmanager durch das Definieren von __enter__ und __exit__-Methoden:

class DatabaseConnection:
    def __init__(self, database_name):
        self.database_name = database_name
        self.connection = None
    
    def __enter__(self):
        """Wird beim Betreten des Kontexts aufgerufen"""
        print(f"Verbindung zur Datenbank herstellen: {self.database_name}")
        self.connection = f"Verbindung zu {self.database_name}"
        return self.connection
    
    def __exit__(self, exc_type, exc_value, traceback):
        """Wird beim Verlassen des Kontexts aufgerufen"""
        print(f"Datenbankverbindung schließen: {self.database_name}")
        if exc_type:
            print(f"Fehler aufgetreten: {exc_type.__name__}: {exc_value}")
        self.connection = None
        return False  # Unterdrückt keine Ausnahmen

# Verwendung eines benutzerdefinierten Kontextmanagers
with DatabaseConnection("user_database") as conn:
    print(f"Verwendung der Verbindung: {conn}")
    print("Datenbankoperationen durchführen...")

Verwendung des contextlib-Moduls zur Erstellung von Kontextmanagern:

from contextlib import contextmanager
import time

@contextmanager
def timer(operation_name):
    """Timer-Kontextmanager"""
    print(f"Starten von {operation_name}")
    start_time = time.time()
    try:
        yield
    finally:
        end_time = time.time()
        print(f"{operation_name} in {end_time - start_time:.2f} Sekunden abgeschlossen")

# Verwendung eines dekoratorbasierten Kontextmanagers
with timer("Datenverarbeitung"):
    # Simulation einer zeitaufwändigen Operation
    time.sleep(1)
    print("Daten werden verarbeitet...")

13. Ausnahmebehandlung

Die Ausnahmebehandlung sorgt für die Robustheit eines Programms und verwendet try, except, else und finally, um Ausnahmen zu verwalten.

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Kann nicht durch Null geteilt werden!")
else:
    print("Division erfolgreich")
finally:
    print("Dies wird immer ausgeführt")

Ausgabe:

Kann nicht durch Null geteilt werden!
Dies wird immer ausgeführt

14. Dateioperationen

Python bietet einfache Methoden zum Lesen und Schreiben von Dateien, die typischerweise mit Kontextmanagern verwendet werden.

14.1 Dateien lesen

Lesen des Inhalts einer Textdatei:

with open("example.txt", "r") as file:
    content = file.read()
    print(content)

Zeilenweises Lesen:

with open("example.txt", "r") as file:
    for line in file:
        print(line.strip())

14.2 Dateien schreiben

Schreiben in eine Textdatei:

with open("output.txt", "w") as file:
    file.write("Hallo, Python!\n")

Inhalt hinzufügen:

with open("output.txt", "a") as file:
    file.write("Neuen Inhalt hinzufügen.\n")

15. Module und Pakete

Module sind Dateien, die Python-Code enthalten, und Pakete sind Verzeichnisse, die mehrere Module enthalten. Importieren Sie Module mit import:

import math
print(math.sqrt(16))  # Ausgabe: 4.0

Beispiel für ein benutzerdefiniertes Modul (angenommen, die Datei heißt mymodule.py):

# mymodule.py
def say_hello():
    return "Hallo aus dem Modul!"

Importieren und Verwenden:

import mymodule
print(mymodule.say_hello())  # Ausgabe: Hallo aus dem Modul!

16. Gültigkeitsbereich und Namensraum

16.1 Gültigkeitsbereich

Der Gültigkeitsbereich definiert den Bereich, in dem eine Variable zugänglich ist. Python folgt der LEGB-Regel für die Variablensuche:

  • L (Lokal): Innerhalb einer Funktion oder Klassenmethode.
  • E (Einschließend): In der äußeren Funktion einer verschachtelten Funktion (Closure).
  • G (Global): Auf Modulebene.
  • B (Eingebaut): Eingebaute Funktionen und Ausnahmen wie print() oder len().
x = "globales x"

def outer_func():
    x = "einschließendes x"
    def inner_func():
        x = "lokales x"
        print(x) # Greift auf lokalen Gültigkeitsbereich x zu
    inner_func()
    print(x) # Greift auf einschließenden Gültigkeitsbereich x zu

outer_func()
print(x) # Greift auf globalen Gültigkeitsbereich x zu

Verwendung von global oder nonlocal zur Änderung von Gültigkeitsbereichsvariablen:

x = "global"
def modify_global():
    global x
    x = "modifiziert"
modify_global()
print(x)  # Ausgabe: modifiziert

16.2 Namensraum

Ein Namensraum ist eine Zuordnung von Namen zu Objekten, wie ein Wörterbuch, dessen Schlüssel Variablennamen und Werte die Objekte sind.

Jedes Modul, jede Funktion und jede Klasse hat ihren eigenen Namensraum, um Namenskonflikte zu vermeiden. Verwenden Sie globals() und locals(), um Namensräume zu inspizieren.

a_variable = 10

def some_function():
    b_variable = 20
    # locals() gibt das aktuelle lokale Namensraum-Wörterbuch zurück
    print(f"Lokale: {locals()}")

print(f"Globale: {globals().keys()}") # Gibt Schlüssel des globalen Namensraums aus
some_function()

17. Generatoren

Generatoren sind spezielle Iteratoren, die Werte bei Bedarf generieren, anstatt alle Werte auf einmal zu erstellen, was sie speichereffizient für große Datensätze macht.

Generatoren verwenden das yield-Schlüsselwort, um Werte träge zurückzugeben:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

for num in fibonacci(5):
    print(num)  # Ausgabe: 0, 1, 1, 2, 3

18. Multithreading

Multithreading ermöglicht es einem Programm, mehrere Operationen gleichzeitig auszuführen, was besonders für I/O-gebundene Aufgaben wie Netzwerkanfragen oder Dateioperationen nützlich ist.

Das threading-Modul von Python bietet Werkzeuge zum Erstellen und Verwalten von Threads. Aufgrund des Global Interpreter Lock (GIL) wird in einem einzelnen Prozess kein echter CPU-Parallelismus erreicht, aber Multithreading verbessert die Leistung bei I/O-gebundenen Aufgaben erheblich.

import threading
import time

def worker(thread_name):
    print(f"Thread {thread_name} startet...")
    time.sleep(2) # Simulation einer zeitaufwändigen Operation
    print(f"Thread {thread_name} abgeschlossen.")

# Threads erstellen
thread1 = threading.Thread(target=worker, args=("A",))
thread2 = threading.Thread(target=worker, args=("B",))

# Threads starten
thread1.start()
thread2.start()

# Warten, bis alle Threads abgeschlossen sind
thread1.join()
thread2.join()

print("Alle Threads abgeschlossen.")

19. Asynchrone Programmierung

Asynchrone Programmierung ist ideal für Szenarien mit hohem I/O-Aufwand und hoher Parallelität und verwendet eine Ereignisschleife, um Aufgaben anstelle von Threads zu verwalten.

Python unterstützt asynchrone Programmierung über die asyncio-Bibliothek und die async/await-Syntax.

  • async def: Definiert eine Coroutine.
  • await: Pausiert die Ausführung der Coroutine, bis ein wartbares Objekt abgeschlossen ist.
import asyncio

async def say_hello():
    print("Hallo")
    await asyncio.sleep(1) # Nicht-blockierender Schlaf, simuliert I/O
    print("Welt")

async def main():
    # Erstellen und Warten auf eine Aufgabe
    await asyncio.create_task(say_hello())

# Haupt-Coroutine ausführen
asyncio.run(main())

Ausgabe:

Hallo
Welt